#include<linux/module.h>
#include<linux/usb.h>
#include<linux/uaccess.h>
#include<linux/slab.h>

#define VENDOR_ID 0x1eab
#define PRODUCT_ID 0x8003
#define MAX_INTERRUPTS 30

static int num=1;

static const struct usb_device_id barcode_scanner_table[]={
	{ USB_DEVICE(VENDOR_ID,PRODUCT_ID) },
	{}
};
MODULE_DEVICE_TABLE(usb,barcode_scanner_table);

struct barcode_scanner_dev{
	struct usb_device *udev; // USB 设备指针
	unsigned char *bulk_in_buffer; // 存储接收数据的缓冲区
	size_t bulk_in_size; // 缓冲区大小
	__u8 bulk_in_endpointAddr; // 数据输入端点地址
	struct usb_interface *interface;
	unsigned char *total_buffer;
	size_t total_size;
	int interrupt_count;
};

// 中断传输的函数，用于处理扫描器传送的数据
// // 修改回调函数
static void barcode_read_callback(struct urb *urb) {
    struct barcode_scanner_dev *dev = urb->context;
    int ret;

    // 检查USB传输状态
    if (urb->status) {
        printk(KERN_ERR "USB 传输错误，错误代码：%d\n", urb->status);
        return;
    }

    // 过滤掉无效的零字节数据
    if (urb->actual_length == 0) {
        printk(KERN_WARNING "接收到空数据包，跳过\n");
        return;
    }

    // 每次读取的数据存储到总缓冲区
    memcpy(dev->total_buffer + dev->total_size, dev->bulk_in_buffer, urb->actual_length);
    dev->total_size += urb->actual_length;
    dev->interrupt_count++;

    // 如果接收到30次中断数据，则拼接完成
    if (dev->interrupt_count >= MAX_INTERRUPTS) {
        // 简单过滤: 排除无效字节
        unsigned char *valid_data = dev->total_buffer;
        size_t valid_size = 0;
        for (size_t i = 0; i < dev->total_size; i++) {
            if (valid_data[i] != 0) {  // 过滤零字节
                valid_data[valid_size++] = valid_data[i];
            }
        }

        printk("第 %d 次扫描完成，拼接的数据为:\n", num++);
        print_hex_dump(KERN_INFO, "Barcode Data: ", DUMP_PREFIX_OFFSET, 16, 1, valid_data, valid_size, true);

        // 重置计数器和总数据缓冲区
        dev->interrupt_count = 0;
        dev->total_size = 0;
    }

    // 继续读取数据
    ret = usb_submit_urb(urb, GFP_KERNEL);
    if (ret) {
        printk(KERN_ERR "重新提交URB失败，错误代码: %d\n", ret);
    }
}


// 设备连接时调用
static int barcode_probe(struct usb_interface *interface,const struct usb_device_id *id){
	struct usb_device *udev=interface_to_usbdev(interface);
	struct barcode_scanner_dev *dev;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	int i;
	int ret;

	printk("条码扫描器连接 (%04X:%04X)\n",id->idVendor,id->idProduct);

	// 分配内存空间
	dev=kzalloc(sizeof(struct barcode_scanner_dev),GFP_KERNEL);
	if(!dev){
		printk(KERN_ERR "分配设备内存空间失败\n");
		return -ENOMEM;
	}

	dev->udev=usb_get_dev(udev);
	iface_desc=interface->cur_altsetting;

	// 查找Bulk-In 端点
	for(i=0;i<iface_desc->desc.bNumEndpoints;i++){
		endpoint=&iface_desc->endpoint[i].desc;

		if(usb_endpoint_is_int_in(endpoint)){
			dev->bulk_in_size=endpoint->wMaxPacketSize;
			dev->bulk_in_endpointAddr=endpoint->bEndpointAddress;
			dev->bulk_in_buffer=kmalloc(dev->bulk_in_size,GFP_KERNEL);
			if(!dev->bulk_in_buffer){
				printk(KERN_ERR "分配 Bulk_in 缓冲区失败\n");
				kfree(dev);
				return -ENOMEM;
			}

			// 为拼接数据分配大缓冲区
			dev->total_buffer = kmalloc(dev->bulk_in_size * MAX_INTERRUPTS, GFP_KERNEL);
			if (!dev->total_buffer) {
				printk(KERN_ERR "分配总缓冲区失败\n");
				kfree(dev->bulk_in_buffer);
				kfree(dev);
				return -ENOMEM;
			}

			dev->total_size = 0;
			dev->interrupt_count = 0;

			break;
		}
	}

	if(!dev->bulk_in_buffer){
		printk(KERN_ERR "未找到 Bulk-In 端点\n");
		kfree(dev->bulk_in_buffer);
		kfree(dev->total_buffer);
		kfree(dev);
		return -ENOMEM;
	}

	// 将设备私有数据绑定到接口
	usb_set_intfdata(interface,dev);

	// 使用UBR来接收数据
	struct urb *urb=usb_alloc_urb(0,GFP_KERNEL);
	if(!urb){
		printk(KERN_ERR "分配URB失败\n");
		kfree(dev->bulk_in_buffer);
		kfree(dev->total_buffer);
		kfree(dev);
		return -ENOMEM;
	}

	usb_fill_int_urb(urb,udev,usb_rcvintpipe(udev,dev->bulk_in_endpointAddr),dev->bulk_in_buffer,dev->bulk_in_size,barcode_read_callback,dev,1);

	ret=usb_submit_urb(urb,GFP_KERNEL);
	if(ret){
		printk(KERN_ERR "提交URB失败，错误代码: %d\n",ret);
		usb_free_urb(urb);
		kfree(dev->bulk_in_buffer);
		kfree(dev);
		return ret;
	}


	printk("条码扫描器初始化成功\n");
	return 0;
}

static void barcode_disconnect(struct usb_interface *interface){
	struct barcode_scanner_dev *dev=usb_get_intfdata(interface);

	usb_set_intfdata(interface,NULL);
	if(dev){
		usb_put_dev(dev->udev);
		kfree(dev->bulk_in_buffer);
		kfree(dev->total_buffer);
		kfree(dev);
	}

	printk("条码扫描器已断开\n");
}

static struct usb_driver barcode_driver={
	.name="barcode_scanner",// 名称
	.id_table=barcode_scanner_table,// 支持的设备表
	.probe=barcode_probe,// 设备连接时调用
	.disconnect=barcode_disconnect,// 设备断开时调用
};

static int __init barcode_init(void){
	int ret = usb_register(&barcode_driver);
	if (ret){
        	printk(KERN_ERR "注册 USB 驱动失败，错误代码：%d\n", ret);
	}
	return ret;
}

static void __exit barcode_exit(void){
	usb_deregister(&barcode_driver);
	printk("条形扫描器驱动卸载成功\n");
}

module_init(barcode_init);
module_exit(barcode_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhuzonghui <puchuchen@outlook.com>");
MODULE_DESCRIPTION("这是一个得力的USB条型扫描器驱动");


